#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
基金爬虫数据监控脚本
监控final_fund_scraper表的数据状态
"""

import sys
import os
from datetime import datetime
import logging

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

try:
    from config import get_database_config
    DB_CONFIG = get_database_config()
except ImportError:
    # 备用配置
    DB_CONFIG = {
        'host': 'localhost',
        'user': 'root',
        'password': 'czya31505',
        'database': 'fund',
        'charset': 'utf8mb4'
    }

try:
    import pymysql
    import pymysql.cursors
    PYMYSQL_AVAILABLE = True
except ImportError:
    PYMYSQL_AVAILABLE = False
    print("警告: pymysql不可用，无法连接数据库")
    sys.exit(1)

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger(__name__)

class FundScraperMonitor:
    """基金爬虫数据监控类"""
    
    def __init__(self):
        self.db_config = DB_CONFIG
    
    def get_db_connection(self):
        """获取数据库连接"""
        try:
            connection = pymysql.connect(
                host=self.db_config['host'],
                user=self.db_config['user'],
                password=self.db_config['password'],
                database=self.db_config['database'],
                charset=self.db_config.get('charset', 'utf8mb4'),
                cursorclass=pymysql.cursors.DictCursor
            )
            return connection
        except Exception as e:
            logger.error(f"数据库连接失败: {e}")
            return None
    
    def get_table_statistics(self):
        """获取表统计信息"""
        connection = self.get_db_connection()
        if not connection:
            return None
        
        try:
            with connection.cursor() as cursor:
                # 检查表是否存在
                cursor.execute("""
                    SELECT COUNT(*) as table_exists 
                    FROM information_schema.tables 
                    WHERE table_schema = %s AND table_name = 'final_fund_scraper'
                """, (self.db_config['database'],))
                
                table_check = cursor.fetchone()
                if table_check and table_check.get('table_exists', 0) == 0:
                    logger.warning("表 final_fund_scraper 不存在")
                    return None
                
                # 获取统计信息
                stats_query = """
                    SELECT 
                        COUNT(*) as total_records,
                        COUNT(DISTINCT fund_code) as unique_funds,
                        COUNT(DISTINCT nav_date) as unique_dates,
                        MIN(nav_date) as earliest_date,
                        MAX(nav_date) as latest_date,
                        MIN(create_date) as first_created,
                        MAX(update_date) as last_updated
                    FROM final_fund_scraper
                """
                
                cursor.execute(stats_query)
                stats = cursor.fetchone()
                
                # 获取最新的一条记录
                latest_record_query = """
                    SELECT 
                        fund_code,
                        fund_name,
                        fund_short_name,
                        nav_date,
                        unit_nav,
                        cumulative_nav,
                        daily_growth_rate,
                        yearly_return,
                        management_fee,
                        create_date,
                        update_date
                    FROM final_fund_scraper 
                    ORDER BY update_date DESC, nav_date DESC 
                    LIMIT 1
                """
                
                cursor.execute(latest_record_query)
                latest_record = cursor.fetchone()
                
                # 获取各日期的记录数分布
                date_distribution_query = """
                    SELECT 
                        nav_date,
                        COUNT(*) as record_count,
                        COUNT(DISTINCT fund_code) as fund_count
                    FROM final_fund_scraper 
                    GROUP BY nav_date 
                    ORDER BY nav_date DESC 
                    LIMIT 10
                """
                
                cursor.execute(date_distribution_query)
                date_distribution = cursor.fetchall()
                
                return {
                    'statistics': stats,
                    'latest_record': latest_record,
                    'date_distribution': date_distribution
                }
                
        except Exception as e:
            logger.error(f"查询统计信息失败: {e}")
            return None
        finally:
            connection.close()
    
    def format_number(self, value):
        """格式化数字显示"""
        if value is None:
            return "N/A"
        if isinstance(value, (int, float)):
            return f"{value:,.2f}" if isinstance(value, float) else f"{value:,}"
        return str(value)
    
    def print_monitor_report(self):
        """打印监控报告"""
        print("\n" + "="*80)
        print(f"基金爬虫数据监控报告 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        print("="*80)
        
        data = self.get_table_statistics()
        if not data:
            print("❌ 无法获取监控数据")
            return
        
        stats = data['statistics']
        latest_record = data['latest_record']
        date_distribution = data['date_distribution']
        
        # 基本统计信息
        print("\n📊 基本统计信息:")
        print("-" * 50)
        print(f"总记录数:        {self.format_number(stats['total_records'])}")
        print(f"基金个数:        {self.format_number(stats['unique_funds'])}")
        print(f"净值日期数:      {self.format_number(stats['unique_dates'])}")
        print(f"最早日期:        {stats['earliest_date']}")
        print(f"最新日期:        {stats['latest_date']}")
        print(f"首次创建时间:    {stats['first_created']}")
        print(f"最后更新时间:    {stats['last_updated']}")
        
        # 最新记录信息
        if latest_record:
            print("\n📈 最新记录详情:")
            print("-" * 50)
            print(f"基金代码:        {latest_record['fund_code']}")
            print(f"基金名称:        {latest_record['fund_name']}")
            print(f"基金简称:        {latest_record['fund_short_name']}")
            print(f"净值日期:        {latest_record['nav_date']}")
            print(f"单位净值:        {self.format_number(latest_record['unit_nav'])}")
            print(f"累计净值:        {self.format_number(latest_record['cumulative_nav'])}")
            print(f"日增长率:        {self.format_number(latest_record['daily_growth_rate'])}%")
            print(f"年化收益率:      {self.format_number(latest_record['yearly_return'])}%")
            print(f"管理费:          {latest_record['management_fee']}")
            print(f"创建时间:        {latest_record['create_date']}")
            print(f"更新时间:        {latest_record['update_date']}")
        
        # 日期分布信息
        if date_distribution:
            print("\n📅 最近10个交易日数据分布:")
            print("-" * 50)
            print(f"{'日期':<12} {'记录数':<10} {'基金数':<10}")
            print("-" * 35)
            for item in date_distribution:
                nav_date_str = str(item['nav_date']) if item['nav_date'] else 'N/A'
                print(f"{nav_date_str:<12} {item['record_count']:<10} {item['fund_count']:<10}")
        
        print("\n" + "="*80)
        print("监控报告完成")
        print("="*80 + "\n")
    
    def check_data_health(self):
        """检查数据健康状态"""
        data = self.get_table_statistics()
        if not data:
            return False
        
        stats = data['statistics']
        issues = []
        
        # 检查是否有数据
        if stats['total_records'] == 0:
            issues.append("❌ 表中没有任何数据")
        
        # 检查数据是否过期（超过3天没有更新）
        if stats['last_updated']:
            from datetime import timedelta
            last_update = stats['last_updated']
            if isinstance(last_update, str):
                last_update = datetime.strptime(last_update, '%Y-%m-%d %H:%M:%S')
            
            if datetime.now() - last_update > timedelta(days=3):
                issues.append(f"⚠️  数据可能过期，最后更新时间: {stats['last_updated']}")
        
        # 检查基金数量是否合理
        if stats['unique_funds'] < 100:
            issues.append(f"⚠️  基金数量较少: {stats['unique_funds']}")
        
        if issues:
            print("\n🚨 数据健康检查发现问题:")
            for issue in issues:
                print(f"  {issue}")
            return False
        else:
            print("\n✅ 数据健康检查通过")
            return True

def main():
    """主函数"""
    monitor = FundScraperMonitor()
    
    # 打印监控报告
    monitor.print_monitor_report()
    
    # 检查数据健康状态
    monitor.check_data_health()

if __name__ == '__main__':
    main()